#ifndef SIMULATIONELEMENT_H_INCLUDED
#define SIMULATIONELEMENT_H_INCLUDED

#include "ConfigElement.h"
#include "ForceElement.h"
#include "ObjectElement.h"

#define SIMULATION_TAG      "simulation"

//defining the attributes
#define SCALE_ATTRIBUTE     "scale"
#define MICRO_VALUE         "micro"
#define NANO_VALUE          "nano"

#define FACTOR_ATTRIBUTE    "factor"

//defining the children elements

namespace OpenNano
{

    enum ScaleOrder { MICRO, NANO };
    typedef std::map<std::string, ForceElement *> ForcesMap;
    typedef std::pair<std::string, ForceElement *> ForcesMapEntry;
    typedef std::map<std::string, ObjectElement *> ObjectsMap;
    typedef std::map<std::string, ObjectElement *> ObjectsMapEntry;


    class OPENNANO_EXPORT SimulationElement : public ConfigElement
    {
        DECLARE_OBJECT_FACTORY( SimulationElement );

        private:
            ScaleOrder _scale;
            double _factor;
            ForcesMap _forces;
            ObjectsMap _objects;

            bool _everything_is_good_so_far;

        protected:
            void attributeFound(TiXmlAttribute * attribute );
            void childElementFound( TiXmlElement * childElement );
            void textFound(const char * text);
            bool postConfiguration();
            void init();

        public:
            ScaleOrder getChosenScale();
            double getChosenFactor();
            const ForcesMap& getForces() const;
            const ObjectsMap& getObjects() const;
            ForceElement * getForce(const std::string& name);
            ObjectElement * getObject(const std::string& name);
    };


}


#endif // SIMULATIONELEMENT_H_INCLUDED
